package contegor.scire.core.queries;

import java.util.Collections;
import java.util.List;

import contegor.scire.core.Connectable;
import contegor.scire.core.Container;
import contegor.scire.core.Id;
import contegor.scire.core.InfiniteSingletonList;
import contegor.scire.core.Link;
import contegor.scire.core.ReturnPoint;
import contegor.scire.core.ReturnPointAdapter;
import contegor.scire.core.Task;
import contegor.scire.core.TaskId;
import contegor.scire.core.Version;

/**
 * Given {@link Query}s that return {@link Link}s, this one returns the {@link Connectable}s source of them.
 *
 * @version $Revision$
 * @author  Héctor Cirbián Pousa ($Author$)
 */
@Version("$Id$")
public class GetSourcesFromLinks extends QueryWithDependencies<Link, Connectable> {
  private static final long serialVersionUID = 5096574264801146532L;

  public GetSourcesFromLinks(Query<Link> dependencie) {
    super(dependencie);
  }

  public GetSourcesFromLinks(Id targetContainerId, Query<Link> ... dependencies) {
    super(targetContainerId, dependencies);
  }
 
  protected GetSourcesFromLinks(TaskId taskId, Id targetContainerId, Query<Link> ... dependencies) {
    super(taskId, targetContainerId, dependencies);
  }

  public void process(Container container) {}

  @Override
  public List<? extends Task<Link>> getDependencies() {
    return this.dependencies;
  }

  @Override
  public List<? extends ReturnPoint<Link>> getDependenciesReturnPoints() {
    if (this.dependencies == null)
      return Collections.emptyList();
    
    ReturnPoint<Link> dependenciesReturnPoint = new ReturnPointAdapter<Link>() {
      public void manage(TaskId taskId, Link result) {
        Connectable src = result.getSource();
        if (src instanceof Container)
          returnPoint.manage(taskId, ((Container)src).getConcepts());
        else
          returnPoint.manage(taskId, src);
      }
      public void manage(TaskId taskId, Exception exception) {
        returnPoint.manage(taskId, exception);
      }
    };

    return new InfiniteSingletonList<ReturnPoint<Link>>(dependenciesReturnPoint, this.dependencies.size());
  }
}